package com.gitee.tianchaohongyu.jdcl.util;

import com.gitee.tianchaohongyu.jdcl.exception.WeakException;

import javax.validation.constraints.NotNull;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.Date;

public class DatetimeUtils {


  /** 日期 */
  private static final String DATE = "yyyy-MM-dd";

  /** 时间 */
  private static final String TIME = "HH:mm:ss";

  /** 日期时间 */
  private static final String[] DATETIMES = {
          "yyyy-MM-dd'T'HH:mm:ss.SSS",
          "yyyy-MM-dd HH:mm:ss.SSS",
          "yyyy-MM-dd HH:mm:ss",
  };

  private static final DateTimeFormatter[] DATETIME_FORMATTERS = Arrays.stream(DATETIMES).map(DateTimeFormatter::ofPattern).toArray(DateTimeFormatter[]::new);
  private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DATE);
  private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(TIME);


  /**
   * 解析新版日期时间
   *
   * @return 时间文本
   */
  public static LocalDateTime parseLocalDateTime(@NotNull String text) {
    for (DateTimeFormatter formatter : DATETIME_FORMATTERS) {
      LocalDateTime datetime = LangUtils.ignore(DateTimeParseException.class, () -> LocalDateTime.parse(text, formatter));
      if (datetime != null) return datetime;
    }
    LocalDate localDate = parseLocalDate(text);
    if (localDate != null) return localDate.atTime(0, 0);
    throw new WeakException("无法解析时间:" + text);
  }


  /**
   * 解析新版日期
   *
   * @return 时间文本
   */
  public static LocalDate parseLocalDate(@NotNull String text) {
    return LocalDate.parse(text, DATE_FORMATTER);
  }


  /**
   * 解析新版时间
   *
   * @return 时间文本
   */
  public static LocalTime parseLocalTime(@NotNull String text) {
    return LocalTime.parse(text, TIME_FORMATTER);
  }

  /**
   * 解析旧版日期时间
   *
   * @return 时间文本
   */
  public static Date parseDate(@NotNull String text) {
    for (String pattern : DATETIMES) {
      Date datetime = LangUtils.ignore(ParseException.class, () -> new SimpleDateFormat(pattern).parse(text));
      if (datetime != null) return datetime;

    }
    Date datetime = LangUtils.ignore(ParseException.class, () -> new SimpleDateFormat(DATE).parse(text));
    if (datetime != null) return datetime;
    datetime = LangUtils.ignore(ParseException.class, () -> new SimpleDateFormat(TIME).parse(text));
    if (datetime != null) return datetime;
    throw new WeakException("无法解析时间:" + text);
  }
}
